﻿using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using ZSZ.Application.IService;
using ZSZ.Core.Entities;
using ZSZ.DTO;
using ZSZ.EntityFramework;
using ZSZ.Service;

namespace ZSZ.Application.Service
{
    public class PermissionService : Repository<PermissionEntity>, IPermissionService
    {
        private readonly ZSZDbContext _ctx = null;
        public long AddPermission(string permName,string description)
        {
            
            bool exists = GetAllDataEntity().Any(p=>p.Name==permName);
            if(exists)
            {
                throw new ArgumentException("权限项已经存在");
            }
            PermissionEntity perm = new PermissionEntity
            {
                Description = description,
                Name = permName
            };
            SaveOrUpdate(perm,true);
            return perm.Id;
            
        }

        public void AddPermIds(long roleId, long[] permIds)
        {
            
            var roleBS 
                = new BaseService<RoleEntity>(_ctx);
            var role = roleBS.GetById(roleId);
            if(role==null)
            {
                throw new ArgumentException("roleId不存在"+roleId);
            }
            
            var perms = GetAllDataEntity()
                .Where(p => permIds.Contains(p.Id)).ToArray();
            foreach(var perm in perms)
            {
                var rolePermission = new RolePermissionEntity
                {
                    PermissionId = perm.Id,
                    RoleId = roleId
                };
                role.RolePermission.Add(rolePermission);
            }

            _ctx.Roles.Attach(role);
            _ctx.Entry(role).State = EntityState.Modified;
        }

        private PermissionDTO ToDTO(PermissionEntity p)
        {
            var dto = new PermissionDTO
            {
                CreateDateTime = p.CreateDateTime,
                Description = p.Description,
                Id = p.Id,
                Name = p.Name
            };
            return dto;
        }

        public PermissionDTO[] GetAll()
        {
            
            return GetAllDataEntity().ToList().Select(p=>ToDTO(p)).ToArray();
            
        }

        public PermissionDTO GetById(long id)
        {
            var pe = GetOneById(id);
            return pe == null ? null : ToDTO(pe);
        }

        public PermissionDTO GetByName(string name)
        {
            var pe = GetAllDataEntity().SingleOrDefault(p=>p.Name==name);
            return pe == null ? null : ToDTO(pe);
        }

        public PermissionDTO[] GetByRoleId(long roleId)
        {
            var bs = new BaseService<RoleEntity>(_ctx);
            return bs.GetById(roleId).RolePermission.ToList().Select(p => ToDTO(p.Permission)).ToArray();
            
        }

        //2,3,4
        //3,4,5
        public void UpdatePermIds(long roleId, long[] permIds)
        {
            
            var roleBS
                = new BaseService<RoleEntity>(_ctx);
            var role = roleBS.GetById(roleId);
            if (role == null)
            {
                throw new ArgumentException("roleId不存在" + roleId);
            }
            role.RolePermission.Clear();
            
            var perms = GetAllDataEntity()
                .Where(p => permIds.Contains(p.Id)).ToList();
            foreach (var perm in perms)
            {
                var rolePermission = new RolePermissionEntity
                {
                    RoleId = roleId,
                    PermissionId = perm.Id
                };
                role.RolePermission.Add(rolePermission);
            }

            _ctx.Roles.Attach(role);
            _ctx.Entry(role).State = EntityState.Modified;

        }

        public void UpdatePermission(long id, string permName, string description)
        {
            var perm = GetOneById(id);
            if(perm==null)
            {
                throw new ArgumentException("id不存在"+id);
            }
            perm.Name = permName;
            perm.Description = description;
            SaveOrUpdate(perm,false);
        }

        public void MarkDeleted(long id)
        {
            DeleteById(id);
        }

        public PermissionService(ZSZDbContext context) : base(context)
        {
            _ctx = context;
        }
    }
}
